package org.example.auth.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.example.auth.Utils.MenuHelper;
import org.example.auth.mapper.SysMenuMapper;
import org.example.auth.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.auth.service.SysRoleMenuService;
import org.example.common.exception.ZspException;
import org.example.model.system.SysMenu;
import org.example.model.system.SysRoleMenu;
import org.example.vo.system.AssginMenuVo;
import org.example.vo.system.MetaVo;
import org.example.vo.system.RouterVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author example
 * @since 2023-04-14
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysRoleMenuService sysRoleMenuService;




    @Override
    public List<SysMenu> findNodes() {
//        查询所有的菜单数据
        List<SysMenu> sysMenuListlist=baseMapper.selectList(null);
//        构建树型结构
    List<SysMenu>resultList= MenuHelper.buildTree(sysMenuListlist);
        return resultList;
    }

    @Override
    public void removeMenuById(Long id) {
//        判断当前的菜单是否有下一层菜单
        LambdaQueryWrapper<SysMenu> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(SysMenu::getParentId,id);
        Integer count=baseMapper.selectCount(wrapper);
        if (count>0){
            throw  new ZspException(201,"菜单不能删除");
        }
        baseMapper.deleteById(id);
    }


    @Override
    public List<SysMenu> findMenuByRoleId(Long roleId) {
        //  1：  查询所有的菜单，添加条件， status=1：
        LambdaQueryWrapper<SysMenu> wrapperSysMenu=new LambdaQueryWrapper<>();
        wrapperSysMenu.eq(SysMenu::getStatus,1);
              List<SysMenu> allMenuList=baseMapper.selectList(wrapperSysMenu);
//        2：根据角色id roleid查询，角色菜单关系表里面，角色id对应的菜单id
        LambdaQueryWrapper<SysRoleMenu> wrapperRoleMenu=new LambdaQueryWrapper<>();
        wrapperRoleMenu.eq(SysRoleMenu::getRoleId,roleId);
     List<SysRoleMenu>  sysRoleMenuList= sysRoleMenuService.list(wrapperRoleMenu);

//        3 根据获取的菜单id，获取菜单对象
      List<Long>  menuIdList=sysRoleMenuList.stream().map(c->c.getMenuId()).collect(Collectors.toList());

//        3.1 拿着菜单id和所有菜单集合里面的id进行比较，如果相同封装
                allMenuList.stream().forEach(item->{
                    if (menuIdList.contains(item.getId())){
                        item.setSelect(true);
                    }else {
                        item.setSelect(false);
                    }
                });
//        4 返回规定树形格式的菜单
                  List<SysMenu> sysMenusList =MenuHelper.buildTree(allMenuList);
        return sysMenusList;
    }

//为角色分配菜单

    @Override
    public void doAssign(AssginMenuVo assginMenuVo) {
//            1根据角色id，删除菜单角色列表，分配数据
        LambdaQueryWrapper<SysRoleMenu> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(SysRoleMenu::getRoleId,assginMenuVo.getRoleId());
        sysRoleMenuService.remove(wrapper);
//        2 从参数里面获取角色新分配的菜单id列表，进行遍历，把每个id数据添加菜单角色列表
       List<Long>  menuIdList=assginMenuVo.getMenuIdList();
       for (Long menuId:menuIdList){
           if (StringUtils.isEmpty(menuId)){
               continue;
           }
           SysRoleMenu sysRoleMenu=new SysRoleMenu();
           sysRoleMenu.setMenuId(menuId);
           sysRoleMenu.setRoleId(assginMenuVo.getRoleId());
           sysRoleMenuService.save(sysRoleMenu);
       }
    }

    @Override
    public List<RouterVo> findUserMenuListByUserId(Long userId) {
        List<SysMenu> sysMenuList = null;
        //1 判断当前用户是否是管理员   userId=1是管理员
        //1.1 如果是管理员，查询所有菜单列表
        if(userId.longValue() == 1) {
            //查询所有菜单列表
            LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysMenu::getStatus,1);
            wrapper.orderByAsc(SysMenu::getSortValue);
            sysMenuList = baseMapper.selectList(wrapper);
        } else {
            //1.2 如果不是管理员，根据userId查询可以操作菜单列表
            //多表关联查询：用户角色关系表 、 角色菜单关系表、 菜单表
            sysMenuList = baseMapper.findMenuListByUserId(userId);
        }
        //2 把查询出来数据列表-构建成框架要求的路由结构
        //使用菜单操作工具类构建树形结构
        List<SysMenu> sysMenuTreeList = MenuHelper.buildTree(sysMenuList);
        //构建成框架要求的路由结构
        List<RouterVo> routerList = this.buildRouter(sysMenuTreeList);
        return routerList;
    }
//构建成框架要求的路由jieg
    private List<RouterVo> buildRouter(List<SysMenu> menus) {
//        创建list集合
        List<RouterVo> routers=new ArrayList<>();
//        menus遍历
        for (SysMenu menu:menus){
            RouterVo router = new RouterVo();
            router.setHidden(false);
            router.setAlwaysShow(false);
            router.setPath(getRouterPath(menu));
            router.setComponent(menu.getComponent());
            router.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
            //下一层数据部分
            List<SysMenu> children = menu.getChildren();
            //如果当前是菜单，需将按钮对应的路由加载出来，如：“角色授权”按钮对应的路由在“系统管理”下面
            if(menu.getType().intValue() == 1) {
                List<SysMenu> hiddenMenuList = children.stream()
                        .filter(item -> !StringUtils.isEmpty(item.getComponent())).collect(Collectors.toList());
                for (SysMenu hiddenMenu : hiddenMenuList) {
                    RouterVo hiddenRouter = new RouterVo();
                    hiddenRouter.setHidden(true);
                    hiddenRouter.setAlwaysShow(false);
                    hiddenRouter.setPath(getRouterPath(hiddenMenu));
                    hiddenRouter.setComponent(hiddenMenu.getComponent());
                    hiddenRouter.setMeta(new MetaVo(hiddenMenu.getName(), hiddenMenu.getIcon()));
                    routers.add(hiddenRouter);
                }
            } else {
                if (!CollectionUtils.isEmpty(children)) {
                    if(children.size() > 0) {
                        router.setAlwaysShow(true);
                    }
                    router.setChildren(buildRouter(children));
                }
            }
            routers.add(router);
        }
        return routers;
    }

    @Override
    public List<String> findUserPermsByUserId(Long userId) {
        //1:判断是否是管理员，是：查询所有按钮列表
        List<SysMenu> sysMenuList=null;
        if (userId.longValue()==1){

            LambdaQueryWrapper<SysMenu> wrapper=new LambdaQueryWrapper<>();
            wrapper.eq(SysMenu::getStatus,1);
            sysMenuList =baseMapper.selectList(wrapper);
        }else {

            //        2：不是的话，根据userid查询可以操作的按钮列表，
//        多表关联查询：用户角色表，角色菜单表，菜单表
            sysMenuList=baseMapper.findMenuListByUserId(userId);
        }

//        3 从查询出来的数据里面，获取可以操作按钮值的list集合返回
   List<String> permList =sysMenuList.stream()
                .filter(item->item.getType()==2)
                .map(item->item.getPerms())
                .collect(Collectors.toList());
        return permList;
    }
    public String getRouterPath(SysMenu menu) {
        String routerPath = "/" + menu.getPath();
        if(menu.getParentId().intValue() != 0) {
            routerPath = menu.getPath();
        }
        return routerPath;
    }
}
